package com.energyfuture.auth.client;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.energyfuture.auth.form.LoginBody;
import com.energyfuture.common.core.exception.BaseException;
import com.energyfuture.domain.IscVo;
import com.energyfuture.system.api.domain.SysUser;
import com.energyfuture.system.api.model.LoginUser;


/**
 * 
 * @ClassName:  CxfClient   
 * @Description:Client
 * @author JJ.Cheng
 * @date:   2020年9月15日 下午4:49:27
 */
@Component
public class CxfClient {

    private static final Logger log = LoggerFactory.getLogger(CxfClient.class);
    
    /**
     * ISC认证地址
     */
    @Value("${ISC.url}")
    private String url;
    
    /**
     * ISC用户信息地址
     */
    @Value("${ISC.getUserInfoUri}")
    private String getUserInfoUri;
	
    /**
     * 客户端id
     */
    @Value("${ISC.clientId}")
    private String clientId;
    
    /**
     * 类型
     */
    @Value("${ISC.grentType}")
    private String grentType;
    
    /**
     * 重定向uri
     */
    @Value("${ISC.redirectUri}")
    private String redirectUri;
    /**
     * 退出登录uri
     */
    @Value("${ISC.logoutUri}")
    private String logoutUri;
    
    @Autowired(required=true)
    private RestTemplate restTemplate;
    
    /**
     * 
     * @Description: 前往ISC进行登录认证,获取用户授权码
     * @author: JJ.Cheng
     * @date: 2021年6月1日下午2:39:46
     * @param LoginBody
     * @param
     * @return
     */
    public String getAccessToken(LoginBody form) {
    	Random r = new Random();
    	String token = null;
    	//测试用假的,接入ISC后, 就需要用ISC返回的token
//    	token = "4d875cc6-7ad3-43f2-a86f-951011c6a47"+r.nextInt(100);
 		IscVo vo = new IscVo();
 		vo.setClient_id(clientId);
 		vo.setGrant_type(grentType);
 		vo.setRedirect_uri(redirectUri);
 		vo.setUsername(form.getUsername());
 		vo.setPassword(form.getPassword());
 		try {
			// -------------------------------> 解决(响应数据可能)中文乱码 的问题
		    List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
		    converterList.remove(1); // 移除原来的转换器
		    // 设置字符编码为utf-8
		    HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
		    converterList.add(1, converter); // 添加新的转换器(注:convert顺序错误会导致失败)
		    restTemplate.setMessageConverters(converterList);
		    
		    // -------------------------------> (选择性设置)请求头信息
		    // HttpHeaders实现了MultiValueMap接口
		    HttpHeaders httpHeaders = new HttpHeaders();
		    // 设置contentType
		    httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
		    // ------------------------------->将请求头、请求体数据，放入HttpEntity中
		    //请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
		    HttpEntity<IscVo> httpEntity = new HttpEntity<IscVo>(vo, httpHeaders);
		 
		    // -------------------------------> URI
		    StringBuffer paramsURL = new StringBuffer(url);
		    URI uri = URI.create(paramsURL.toString());
		    
		    //-------------------------------> 执行请求并返回结果
		    // 此处的泛型  对应 响应体数据   类型;即:这里指定响应体的数据装配为String
		    ResponseEntity<String> response = 
		            restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);
		    // -------------------------------> 响应信息
		    //响应码,如:401、302、404、500、200等
		    System.err.println(response.getStatusCodeValue());
//			    // 响应头
//			    System.err.println(response.getHeaders());
//			    // 响应体
		    String result = null;
		    if(response.hasBody()) {
		    	result = response.getBody();
		    }
		    if(result != null ) {
		    	JSONObject json = JSONObject.parseObject(result);
			    token = json.getString("access_token");
		    }
		} catch (Exception e) {
			log.error("ISC登录认证失败:"+e);
			throw new BaseException("登录ISC失败!");
		}
		return token;
    }
    
    /**
     * 
     * @Description: 根据token获取用户信息
     * @author: JJ.Cheng
     * @date: 2021年6月1日下午3:43:10
     * @param token
     * @return
     */
    public LoginUser getUserInfo(String token){
    	//根据token拿用户信息
    	LoginUser userinfo = new LoginUser();
    	SysUser sys = new SysUser();
    	//用户id必须是数据库中包含的
    	sys.setUserId("1");
    	sys.setUserName("test");
    	sys.setIsUpdatePassword(1);
    	userinfo.setExpireTime(1800L);
    	userinfo.setSysUser(sys);
    	userinfo.setLoginTime(1622541596687L);
    	Set<String> set = new HashSet<String>();
    	Set<String> set1 = new HashSet<String>();
    	//角色类型得给,不然没权限 后面可根据从ISC获取到的用户角色给相应的权限
    	set1.add("*:*:*");
    	set.add("admin");
    	userinfo.setRoles(set);
    	userinfo.setPermissions(set1);
 		try {
			// -------------------------------> 解决(响应数据可能)中文乱码 的问题
		    List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
		    converterList.remove(1); // 移除原来的转换器
		    // 设置字符编码为utf-8
		    HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
		    converterList.add(1, converter); // 添加新的转换器(注:convert顺序错误会导致失败)
		    restTemplate.setMessageConverters(converterList);
		    
		    // -------------------------------> (选择性设置)请求头信息
		    // HttpHeaders实现了MultiValueMap接口
		    HttpHeaders httpHeaders = new HttpHeaders();
		    // 设置contentType
		    httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
		    // ------------------------------->将请求头、请求体数据，放入HttpEntity中
		    //请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
		    //参数
		    Map<String, String> param = new HashMap<>();
		    param.put("access_token", token);
		    HttpEntity<Map<String,String>> httpEntity = new HttpEntity<Map<String,String>>(param, httpHeaders);
		 
		    // -------------------------------> URI
		    StringBuffer paramsURL = new StringBuffer(getUserInfoUri);
		    URI uri = URI.create(paramsURL.toString());
		    
		    //-------------------------------> 执行请求并返回结果
		    // 此处的泛型  对应 响应体数据   类型;即:这里指定响应体的数据装配为String
		    ResponseEntity<String> response = 
		            restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);
		    // -------------------------------> 响应信息
		    //响应码,如:401、302、404、500、200等
		    System.err.println(response.getStatusCodeValue());
//			    // 响应头
//			    System.err.println(response.getHeaders());
//			    // 响应体
		    String result = null;
		    if(response.hasBody()) {
		    	result = response.getBody();
		    }
		    //返回json示例
		    //{"iscUserId":"1","scop":"0","provinceId":"sgcc","iscUserSourceId":"soaadmin","iscAdCode":"soaadmin","logintime":"1597821470300","name":"超管理员","ip":"27.196.216.224" ,"baseOrgId":"1"}
		    //字段说明
		    /*iscUserId  用户ID
		    scop 用户类型
		    provinceId 网省ID
		    iscUserSourceId  登录名
		    soaadmin namecode
		    logintime 登陆时间
		    name 名称
		    ip 登陆IP

		    baseOrgId 基准组织ID */
		    if(result != null ) {
		    	JSONObject json = JSONObject.parseObject(result);
			    token = json.getString("access_token");
		    }
		} catch (Exception e) {
			log.error("ISC获取用户信息失败:"+e);
			throw new BaseException("ISC获取用户信息失败!");
		}
    	
    	return userinfo;
    }
}
